package com.xyz.vod.service.Impl;

import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.DeleteVideoRequest;
import com.aliyuncs.vod.model.v20170321.DeleteVideoResponse;
import com.xyz.async.AsyncService;
import com.xyz.entity.R;
import com.xyz.exceptionhandler.BusinessException;
import com.xyz.vod.service.VodService;
import com.xyz.utils.AliyunVodSDKUtils;
import com.xyz.utils.VodPropertiesUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 视频上传实现类
 * @author zsr
 * @date 2021/6/16 9:21
 */
@Service
@Slf4j
public class VodServiceImpl implements VodService {

    @Autowired
    private AsyncService asyncService;

    @Value("${ffmpegLocalPath}")
    private String localPath;

    @Value("${serverIp}")
    private String serverIp;

    @Override
    public String uploadAly(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            String originalFilename = file.getOriginalFilename();
            String title = originalFilename.substring(0, originalFilename.lastIndexOf("."));

            //TODO 加密上传
            UploadStreamRequest request = new UploadStreamRequest(
                    VodPropertiesUtil.ACCESS_KEY_ID,
                    VodPropertiesUtil.ACCESS_KEY_SECRET,
                    title, originalFilename, inputStream);

            UploadVideoImpl uploader = new UploadVideoImpl();
            UploadStreamResponse response = uploader.uploadStream(request);

            //如果设置回调URL无效，不影响视频上传，可以返回VideoId同时会返回错误码。
            // 其他情况上传失败时，VideoId为空，此时需要根据返回错误码分析具体错误原因
            String videoId = response.getVideoId();
            if (!response.isSuccess()) {
                String errorMessage = "阿里云上传错误：" + "code：" + response.getCode() + ", message：" + response.getMessage();
                log.warn(errorMessage);
                if(StringUtils.isEmpty(videoId))
                    throw new BusinessException(20001, errorMessage);
            }

            return videoId;
        } catch (IOException e) {
            throw new BusinessException(20001, "guli vod 服务上传失败");
        }
    }

    @Override
    public void removeVideo(String videoId) {
        try{
            DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(
                    VodPropertiesUtil.ACCESS_KEY_ID,
                    VodPropertiesUtil.ACCESS_KEY_SECRET);

            DeleteVideoRequest request = new DeleteVideoRequest();

            request.setVideoIds(videoId);

            DeleteVideoResponse response = client.getAcsResponse(request);

            //System.out.print("RequestId = " + response.getRequestId() + "\n");

        }catch (ClientException e){
            throw new BusinessException(20001, "视频删除失败");
        }
    }

    //删除多个视频
    @Override
    public boolean removeVideoList(List<String> videoIdList) {
        try {
            // 初始化对象
            DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(VodPropertiesUtil.ACCESS_KEY_ID,
                    VodPropertiesUtil.ACCESS_KEY_SECRET);
            // 创建删除视频request对象
            DeleteVideoRequest request = new DeleteVideoRequest();

            // videoIdList值转成 1,2,3
            String videoIds = Strings.join(videoIdList, ',');

            // 向request设置视频id
            request.setVideoIds(videoIds);
            // 调用初始化对象的方法实现删除
            client.getAcsResponse(request);
            return true;
        } catch (ClientException e) {
            System.out.print("ErrorMessage = " + e.getLocalizedMessage());
            return false;
        }
    }

    @Override
    public String uploadLocalVideo(MultipartFile file) {
        try {
            // 获取原始文件名
            String originalFilename = file.getOriginalFilename();
            // 获取文件扩展名
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            // 生成新的文件名（使用时间戳）
            String newFileName = System.currentTimeMillis() + extension;

            // 定义本地存储路径
            // 创建目录
            File dir = new File(localPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }

            // 保存文件
            File dest = new File(localPath + "/" + newFileName);
            file.transferTo(dest);

            // 构造返回URL
            String videoUrl = serverIp+":8086/api4xyz/eduoss/fileoss/getLocalVideo" + localPath + "/" + newFileName;

            return videoUrl;
        } catch (IOException e) {
            R.error().message("视频上传失败：" + e.getMessage());
        }
        return null;
    }

    @Override
    public String uploadLocalVideoM3u8(MultipartFile file) {
        try {
            // 获取原始文件名
            String originalFilename = file.getOriginalFilename();
            // 获取文件扩展名
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            // 生成新的文件名（使用时间戳）
            String fileNameWithoutExtension = originalFilename.substring(0, originalFilename.lastIndexOf("."));
            String newFileName = System.currentTimeMillis() + "";
            
            // 定义本地存储路径
//            String localPath = "/Users/gds/project2025/tmp/eduUpload/videos";
            String videoPath = localPath + "/" + newFileName + extension;
            String m3u8Path = localPath + "/" + newFileName;
            
            // 创建目录
            File dir = new File(localPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            
            // 创建m3u8目录
            File m3u8Dir = new File(m3u8Path);
            if (!m3u8Dir.exists()) {
                m3u8Dir.mkdirs();
            }

            // 保存原始文件
            File dest = new File(videoPath);
            file.transferTo(dest);
            
            // 使用ffmpeg将视频转换为m3u8格式
            String m3u8FilePath = m3u8Path + "/index.m3u8";
            CompletableFuture<Integer> integerCompletableFuture = asyncService.processVideoToM3u8(videoPath, m3u8FilePath);
//            ProcessBuilder processBuilder = new ProcessBuilder();
//            processBuilder.command("ffmpeg", "-i", videoPath,
//                    "-codec", "copy",
//                    "-start_number", "0",
//                    "-hls_time", "10",
//                    "-hls_list_size", "0",
//                    "-f", "hls",
//                    m3u8FilePath);
//
//            Process process = processBuilder.start();
//            int exitCode = process.waitFor();
//
//            if (exitCode != 0) {
//                throw new RuntimeException("ffmpeg转码失败，退出码：" + exitCode);
//            }
            
            // 构造返回URL
            String videoUrl = serverIp+"/api4xyz/eduoss/fileoss/getLocalVideo" + m3u8Path + "/index.m3u8";

            return videoUrl;
        } catch (IOException | InterruptedException e) {
            R.error().message("视频上传失败：" + e.getMessage());
        }
        return null;
    }
}
